/* ***********************************************************************
 * Copyright (C) 1992-2014 中国南方航空股份有限公司.
 *
 * Created [2014-5-5 下午2:15:17] by FMS Team
 * ***********************************************************************
 *
 * fms-udp
 * ***********************************************************************
 */
package com.foreveross.law.base.dao.impl;

import java.io.Serializable;
import java.lang.reflect.Field;
import java.util.List;
import java.util.Map;

import org.apache.commons.beanutils.PropertyUtils;
import org.springframework.stereotype.Repository;

import com.foreveross.law.base.dao.CrudRepository;
import com.foreveross.law.common.util.SQLUtil;

/**
 * <p>
 * com.csair.udp.common.repository.impl.CrudRepositoryImpl.java
 * </p>
 * 
 * @author liaocw(mail)
 * @version $Revision$ $Date$
 * @Modified by liaocw(mail) description
 * @purpose add this file description here
 */
@Repository()
public class CrudRepositoryImpl<T, ID extends Serializable> extends
		BaseRepositoryImpl<T> implements CrudRepository<T, ID> {

	// @Resource(name = "sqlSessionFactory")
	// public void setSqlSessionFactory(SqlSessionFactory sqlSessionFactory) {
	// super.setSqlSessionFactory(sqlSessionFactory);
	// }

	/*
	 * @param clazz
	 * 
	 * @param id
	 * 
	 * @return
	 * 
	 * @see com.csair.udp.common.repository.CrudRepository#get(java.lang.Class,
	 * java.io.Serializable)
	 */
	@Override
	public T get(Class<T> clazz, Serializable id) {
		return sqlSession.selectOne(this.getFindByPrimaryKeyQuery(clazz), id);
	}

	/*
	 * @param clazz
	 * 
	 * @param entity
	 * 
	 * @return
	 * 
	 * @see com.csair.udp.common.repository.CrudRepository#save(java.lang.Class,
	 * java.lang.Object)
	 */
	@SuppressWarnings("unchecked")
	@Override
	public ID save(Class<T> clazz, T entity) {
		Serializable primaryKey = null;
		sqlSession.insert(getInsertQuery(clazz), entity);
		// get pk value from entity
		try {
			Field pk = clazz.getDeclaredField("PROP_KEY");
			Object obj = pk.get(null);
			if (obj != null) {
				String key = pk.get(null).toString();
				obj = PropertyUtils.getProperty(entity, key);
				if (obj != null)
					primaryKey = (Serializable) obj;
			}

		} catch (Exception e) {
			// e.printStackTrace();
		}

		return (ID) primaryKey;

	}

	/*
	 * @param clazz
	 * 
	 * @param entity
	 * 
	 * @see
	 * com.csair.udp.common.repository.CrudRepository#update(java.lang.Class,
	 * java.lang.Object)
	 */
	@Override
	public void update(Class<T> clazz, T entity) {
		this.update(getUpdateQuery(clazz), entity);

	}

	/*
	 * @param clazz
	 * 
	 * @param id
	 * 
	 * @see
	 * com.csair.udp.common.repository.CrudRepository#delete(java.lang.Class,
	 * java.io.Serializable)
	 */
	@Override
	public void delete(Class<T> clazz, ID id) {
		sqlSession.delete(getDeleteQuery(clazz), id);

	}

	/*
	 * @param clazz
	 * @param param
	 * 
	 * @return
	 * 
	 * @see
	 * com.csair.udp.common.repository.CrudRepository#findAll(java.lang.Class)
	 */
	@Override
	public List<T> findAll(Class<T> clazz) {
		return this.find(this.getPageQuery(clazz));
	}
	
	/*
	 * @param clazz
	 * @param param
	 * 
	 * @return
	 * 
	 * @see
	 * com.csair.udp.common.repository.CrudRepository#findAll(java.lang.Class,Map<String,Object>)
	 */
	@Override
	public List<T> findAll(Class<T> clazz,Map<String,Object> param) {
		return this.find(this.getPageQuery(clazz),param);
	}

	/*
	 * @param clazz
	 * 
	 * @param parameter
	 * 
	 * @return
	 * 
	 * @see
	 * com.csair.udp.common.repository.CrudRepository#getCount(java.lang.Class,
	 * java.util.Map)
	 */
	@Override
	public Long getCount(Class<T> clazz, Map<String, ?> parameter) {
		return this.findNumber(this.getPageCountQuery(clazz), parameter);
	}

	public String getFindByPrimaryKeyQuery(Class<T> clazz) {
		return SQLUtil.getFindByPrimaryKeyQuery(clazz);
	}

	public String getInsertQuery(Class<T> clazz) {
		return SQLUtil.getInsertQuery(clazz);
	}

	public String getUpdateQuery(Class<T> clazz) {
		return SQLUtil.getUpdateQuery(clazz);
	}

	public String getDeleteQuery(Class<T> clazz) {
		return SQLUtil.getDeleteQuery(clazz);
	}

	public String getPageQuery(Class<T> clazz) {
		return SQLUtil.getPageQuery(clazz);

	}

	public String getPageCountQuery(Class<T> clazz) {
		return SQLUtil.getPageCountQuery(clazz);
	}

}
